﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MARZ_Script.analysis;
using MARZ_Script.node;

namespace SableCC15.CodeGeneration
{
    public class DeclarationCodeGen : DepthFirstAdapter
    {
        private PExpression _value;
        public override void CaseADeclVarDecl(MARZ_Script.node.ADeclVarDecl node)
        {
            node.GetDecl().Apply(this);
        }

        public override void CaseAInitDeclVarDecl(MARZ_Script.node.AInitDeclVarDecl node)
        {
            _value = node.GetExpression();
            if (node.GetExpression().ToString().Trim().Contains("List"))
            {
                node.GetDecl().Apply(this);
                node.GetExpression().Apply(new ExpressionCodeGen());
                return;
            }
            if (node.NodeType == "templates")
            {
                //Let entity player Be p
                //Player p = new player();
                //_value = node.GetExpression().ToString().Trim();
                //Utility.Emit(_value);
                node.GetExpression().Apply(new ExpressionCodeGen());
                node.GetDecl().Apply(this);
                _value = null;
                return;
            }
            if (node.NodeType == "coord")
            {
                node.GetDecl().Apply(this);
                Utility.Emit("(");
                node.GetExpression().Apply(new CoordXCodeGen());
                Utility.Emit(",");
                node.GetExpression().Apply(new CoordYCodeGen());
                Utility.Emit(");");
                return;
            }

            
            node.GetDecl().Apply(this);
            
            _value = null;
        }

        public override void CaseADecl(MARZ_Script.node.ADecl node)
        {
            string type = node.GetType().ToString().Trim();
            if (type == "float")
                type = "double";
            string id = node.GetId().Text;
            //We can have variables or lists or templates
            if (type == "entity")
            {
                Utility.Emit(" " + id + "= new ");
                _value.Apply(new ExpressionCodeGen());
                Utility.Emit("()");
                Utility.Emit(";");
                return;
            }
            if (node.GetTList() != null)
            {
                Utility.Emit("List<" + type + "> " + id + " =" + " new List<" + type + ">" + "()");
                Utility.Emit(";");
            }
            else if (_value == null)
            {
                Utility.Emit(type + " " + id);
                Utility.Emit(";");
            }
            else if (_value.ToString().Trim().Contains("List"))
            {
                Utility.Emit(type + " " + id + " " + "=");
                return;
            }
            else
            {
                //TODO HERE IS THE PROBLEM 
                if (type.Equals("coord"))
                {
                    Utility.Emit("Coord " + id + " " + "=" + "new " + "Coord");
                    return;
                }
                else
                {
                    Utility.Emit(type + " " + id + " " + "=");
                    _value.Apply(new ExpressionCodeGen());
                    Utility.Emit(";");

                }

            }
        }
        public override void CaseARecurvParams(MARZ_Script.node.ARecurvParams node)
        {

            base.CaseARecurvParams(node);
        }
        public override void CaseAParam(MARZ_Script.node.AParam node)
        {
            if ((node.GetType().ToString().Trim() == "coord"))
                Utility.Emit("Coord ");
            else if (node.GetType().ToString().Trim() == "float")
                Utility.Emit("double ");
            else
                Utility.Emit(node.GetType().ToString());

            Utility.Emit(node.GetId().ToString());

            if (node.Parent() is ARecurvParams)
                Utility.Emit(",");
        }
    }
}
